﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TestSystem.Model;
using TestSystem.Model.FrameworkEnumeration;
using Tools;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Mvc;

namespace MVCClient.Controllers
{
    /// <summary>
    /// 免登录考试
    /// </summary>
    [Public]
    public class AvoidTheLoginTestController : BaseController
    {
        [Public]
        public async Task<IActionResult> AtctivitiesList()
        {
            var list = await DC.Set<ExaminationSetup>()
                .Where(x => x.CourseEnum == CourseEnum.正常)
                .Where(x => x.StrTime <= DateTime.Now && DateTime.Now <= x.EndTime)
                .ToListAsync();
            return View(list);
        }
        [Public]
        [ActionDescription("参加考试")]
        public async Task<IActionResult> SignUp()
        {

            #region 公共账号自动登录

            var user = DC.Set<FrameworkUserBase>()
                 .Include(x => x.UserRoles).Include(x => x.UserGroups)
               .Where(x => x.ITCode.ToLower() == "admin")
               .SingleOrDefault();
            var roleIDs = user.UserRoles.Select(x => x.RoleId).ToList();
            var groupIDs = user.UserGroups.Select(x => x.GroupId).ToList();
            var dpris = DC.Set<DataPrivilege>()
                .Where(x => x.UserId == user.ID || (x.GroupId != null && groupIDs.Contains(x.GroupId.Value)))
                .Distinct()
                .ToList();
            ProcessTreeDp(dpris);
            LoginUserInfo rv = new LoginUserInfo
            {
                Id = user.ID,
                ITCode = user.ITCode,
                Name = user.Name,
                PhotoId = user.PhotoId,
                Roles = DC.Set<FrameworkRole>().Where(x => user.UserRoles.Select(y => y.RoleId).Contains(x.ID)).ToList(),
                Groups = DC.Set<FrameworkGroup>().Where(x => user.UserGroups.Select(y => y.GroupId).Contains(x.ID)).ToList(),
                DataPrivileges = dpris
            };
            LoginUserInfo = rv;
            AuthenticationProperties properties = new AuthenticationProperties
            {
                IsPersistent = true,
                ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromDays(30))
            };
            var principal = rv.CreatePrincipal();
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, properties);


            #endregion
            ViewBag.RotationChart = await DC.Set<RotationChart>().ToListAsync();
            return View();
        }
        [Public]
        public async Task<IActionResult> GetTestPaper(int id, string username, string unitwork)
        {
            var model = await DC.Set<ExaminationSetup>()
                .SingleOrDefaultAsync(x => x.ID == id);
            ViewBag.cid = id;
            //单选
            var dxlist = await GetQuestions(DC.Set<QuestionType>().FirstOrDefault(x => x.Name == "单选").ID, model.DXNumer, model.Subject);
            ViewBag.dxlist = dxlist;
            //多选
            var dsxlist = await GetQuestions(DC.Set<QuestionType>().FirstOrDefault(x => x.Name == "多选").ID, model.DSXNumer, model.Subject);
            ViewBag.dsxlist = dsxlist;
            //判断
            var pdlist = await GetQuestions(DC.Set<QuestionType>().FirstOrDefault(x => x.Name == "判断").ID, model.PDNumer, model.Subject);
            ViewBag.pdlist = pdlist;



            ViewBag.dt = DateTime.Now.AddMinutes(model.TestTime).ToString("yyyy-MM-dd HH:mm:ss");
            ViewBag.totalmillisec = model.TestTime * 60 * 1000;
            ViewBag.totalmillisecht = (model.TestTime - 5) * 60 * 1000;
            var dxlistidStr = string.Join(",", dxlist.Select(x => x.ID).ToList());
            var dxlistanStr = string.Join(",", dxlist.Select(x => x.Anwser).ToList());

            var dsxlistidStr = string.Join(",", dsxlist.Select(x => x.ID).ToList());
            var dsxlistanStr = string.Join(",", dsxlist.Select(x => x.Anwser).ToList());

            var pdlistidStr = string.Join(",", pdlist.Select(x => x.ID).ToList());
            var pdlistanStr = string.Join(",", pdlist.Select(x => x.Anwser).ToList());

            RecordNoAccount lr = new RecordNoAccount
            {
                ExaminationSetupID = id,
                ParticipationTime = DateTime.Now,
                UserName = username,
                UnitWork = unitwork,
                QuestionId = dxlistidStr + "|" + dsxlistidStr + "|" + pdlistidStr,
                QuestionAnswer = dxlistanStr + "|" + dsxlistanStr + "|" + pdlistanStr,
            };
            await DC.Set<RecordNoAccount>().AddAsync(lr);
            await DC.SaveChangesAsync();
            ViewBag.lid = lr.ID;
            return View();
        }
        [Public]
        [ActionDescription("分数结算")]
        public async Task<IActionResult> Fraction()
        {
            int cid = Convert.ToInt32(Request.Form["cid"]);
            int lid = Convert.ToInt32(Request.Form["lid"]);
            var course = await DC.Set<ExaminationSetup>()
                .SingleOrDefaultAsync(x => x.ID == cid);
            var lr = await DC.Set<RecordNoAccount>()
                   .SingleOrDefaultAsync(x => x.ID == lid);
            string[] userDX = new string[course.DXNumer];
            for (int i = 1; i < (course.DXNumer + 1); i++)
            {
                string temp = i.ToString() + " DC";
                string answerDX = Request.Form[temp];
                userDX[i - 1] = answerDX;
            }
            string[] userDSX = new string[course.DSXNumer];
            for (int i = 1; i < (course.DSXNumer + 1); i++)
            {
                string temp = i.ToString() + " DXC";
                string answerDXX = Request.Form[temp];
                if (answerDXX != null)
                {
                    userDSX[i - 1] = answerDXX.Replace(",", "");
                }
                else
                {
                    userDSX[i - 1] = answerDXX;
                }
            }
            string[] userPD = new string[course.PDNumer];
            for (int i = 1; i < (course.PDNumer + 1); i++)
            {
                string temp = i.ToString() + " PD";
                string answerPD = Request.Form[temp];
                userPD[i - 1] = answerPD;
            }
            string answerEn = lr.QuestionAnswer;
            string[] answerEnArr = answerEn.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
            string[] userDXEn = answerEnArr[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            string[] userDSXEn = answerEnArr[1].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            string[] userPDEn = answerEnArr[2].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            int userDXEnRight = 0;
            int userDSXEnRight = 0;
            int userPDEnRight = 0;
            for (int i = 0; i < userDXEn.Length; i++)
            {
                if (userDX[i] == userDXEn[i])
                {
                    userDXEnRight++;
                }
            }
            for (int i = 0; i < userDSXEn.Length; i++)
            {
                if (userDSX[i] == userDSXEn[i])
                {
                    userDSXEnRight++;
                }
            }
            for (int i = 0; i < userPDEn.Length; i++)
            {
                if (userPD[i] == userPDEn[i])
                {
                    userPDEnRight++;
                }
            }
            //判分
            var fen = userDXEnRight * course.DXScore + userDSXEnRight * course.DSXScore + userPDEnRight * course.PDScore;
            lr.Achievement = fen;
            lr.ExamineeAnswers = string.Join(",", userDX) + "|" + string.Join("", userDSX) + "|" + string.Join(",", userPD);
            DC.Set<RecordNoAccount>().Update(lr);
            await DC.SaveChangesAsync();
            ViewBag.fen = fen;
            ViewBag.cid = cid;
            return View();
        }
        [Public]
        [ActionDescription("查看证书")]
        public async Task<IActionResult> Certificate(int id, string username, string unitwork, string fen)
        {
            var course = await DC.Set<ExaminationSetup>()
                 .SingleOrDefaultAsync(x => x.ID == id);
            var seal = await DC.Set<Seal>()
                 .SingleOrDefaultAsync(x => x.ID == course.SealId);
            var imgid = seal.PhotoId;
            var file = await DC.Set<FileAttachment>()
                 .SingleOrDefaultAsync(x => x.ID == imgid);
            var imgdata = file.FileData;
            var img = ImgData.ReturnPhoto(imgdata);
            int width = img.Size.Width;   // 图片的宽度
            int height = img.Size.Height;   // 图片的高度
            Graphics g = Graphics.FromImage(img);
            StringFormat TitleFormat = new StringFormat();
            StringFormat TitleFormat1 = new StringFormat();
            TitleFormat.Alignment = StringAlignment.Center; //居中
            TitleFormat1.LineAlignment = StringAlignment.Far;
            g.DrawString("合格证书", new Font("黑体", 25), Brushes.Black, new Point(width / 2, 250), TitleFormat);
            g.DrawString(unitwork + username + ":", new Font("宋体", 15), Brushes.Black, new Point(150, 350));
            g.DrawString(course.Title, new Font("宋体", 15), Brushes.Black, new Point(150, 400));
            g.DrawString("考成成绩" + fen + "分", new Font("宋体", 15), Brushes.Red, new Point(150, 450));
            g.DrawString("WTM在线考试", new Font("黑体", 15), Brushes.Black, new Point(width / 2 + 35, height - 150), TitleFormat1);
            //g.DrawString("证件号：00001", new Font("黑体", 15), Brushes.Black, new Point(width / 8, height - 175));
            var imgre = ImgData.PhotoImageInsert(img);
            await Response.Body.WriteAsync(imgre, 0, imgdata.Count());
            return new EmptyResult();
        }
        /// <summary>
        /// 获取题库
        /// </summary>
        /// <param name="questionTypeEnum">类型</param>
        /// <param name="number">数量</param>
        /// <returns></returns>
        [Public]
        public async Task<List<Question>> GetQuestions(int questionType, int number, string sub)
        {
            List<Question> QuestionList = new List<Question>();
            var collection = await DC.Set<Question>()
                .Where(x => x.Subject == sub)
                .Where(x => x.QuestionTypeID == questionType)
                .ToListAsync();
            Random rd = new Random();
            for (int i = 0; i < number; i++)
            {
                int index = rd.Next(collection.Count());
                var model = collection[index];
                QuestionList.Add(model);
                collection.Remove(model);
            }
            return QuestionList;
        }

        #region 登录方法
        private void ProcessTreeDp(List<DataPrivilege> dps)
        {
            var dpsSetting = GlobalServices.GetService<Configs>().DataPrivilegeSettings;
            foreach (var ds in dpsSetting)
            {
                if (typeof(ITreeData).IsAssignableFrom(ds.ModelType))
                {
                    var ids = dps.Where(x => x.TableName == ds.ModelName).Select(x => x.RelateId).ToList();
                    if (ids.Count > 0 && ids.Contains(null) == false)
                    {
                        List<Guid> tempids = new List<Guid>();
                        foreach (var item in ids)
                        {
                            if (Guid.TryParse(item, out Guid g))
                            {
                                tempids.Add(g);
                            }
                        }
                        List<Guid> subids = new List<Guid>();
                        subids.AddRange(GetSubIds(tempids.ToList(), ds.ModelType));
                        subids = subids.Distinct().ToList();
                        subids.ForEach(x => dps.Add(new DataPrivilege
                        {
                            TableName = ds.ModelName,
                            RelateId = x.ToString()
                        }));
                    }
                }
            }
        }

        private IEnumerable<Guid> GetSubIds(List<Guid> p_id, Type modelType)
        {
            var basequery = DC.GetType().GetTypeInfo().GetMethod("Set").MakeGenericMethod(modelType).Invoke(DC, null) as IQueryable;
            var subids = basequery.Cast<ITreeData>().Where(x => p_id.Contains(x.ParentId.Value)).Select(x => x.ID).ToList();
            if (subids.Count > 0)
            {
                return subids.Concat(GetSubIds(subids, modelType));
            }
            else
            {
                return new List<Guid>();
            }
        }
        #endregion




    }
}